import type { ErrorListener } from '@/config/router/RouterGuard'
import type { NavigationGuardWithThis, NavigationHookAfter, Router } from 'vue-router'


/**
 * 路由守卫管理器
 *
 * 按名称注册和取消导航守卫
 */
export class RouterGuardManager {

    /**
     * Vue Router 实例
     */
    private readonly router: Router

    private readonly beforeEachRegistry: Map<String, Function> = new Map<String, Function>()

    private readonly beforeResolveRegistry: Map<String, Function> = new Map<String, Function>()

    private readonly afterEachRegistry: Map<String, Function> = new Map<String, Function>()

    private readonly onErrorRegistry: Map<String, Function> = new Map<String, Function>()

    public constructor(router: Router) {
        this.router = router
    }

    public beforeEach(name: string, guard: NavigationGuardWithThis<any>): void {
        const removeFun = this.router.beforeEach(guard)
        this.beforeEachRegistry.set(name, removeFun)
    }

    public removeBeforeEach(name: string): void {
        const removeFun = this.beforeEachRegistry.get(name)
        removeFun && removeFun()
    }

    public beforeResolve(name: string, guard: NavigationGuardWithThis<any>): void {
        const removeFun = this.router.beforeResolve(guard)
        this.beforeResolveRegistry.set(name, removeFun)
    }

    public removeBeforeResolve(name: string): void {
        const removeFun = this.beforeResolveRegistry.get(name)
        removeFun && removeFun()
    }

    public afterEach(name: string, guard: NavigationHookAfter): void {
        const removeFun = this.router.afterEach(guard)
        this.afterEachRegistry.set(name, removeFun)
    }

    public removeAfterEach(name: string): void {
        const removeFun = this.afterEachRegistry.get(name)
        removeFun && removeFun()
    }

    public onError(name: string, guard: ErrorListener): void {
        const removeFun = this.router.onError(guard)
        this.onErrorRegistry.set(name, removeFun)
    }

    public removeOnError(name: string): void {
        const removeFun = this.onErrorRegistry.get(name)
        removeFun && removeFun()
    }

}
